﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using ST.Common.Data;
using ST.Common.Util;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using ST.Buz.Base;
using ST.Buz.Base.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using ST.Buz.Base.Enums;
using ST.Common.Util.Security;
using Microsoft.Data.SqlClient;
using ST.Buz.Base.ViewModel;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace ST.Buz.Service
{
	public partial interface IServiceSysUser
	{
		/// <summary>
		/// 获取用户详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		Sys_User GetEditDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 获取用户详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		Sys_User GetViewDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 获取分页列表
		/// </summary>
		PageData GetPageList(VMS_Sys_User searchModel);

		/// <summary>
		/// 列表
		/// </summary>
		List<VML_Sys_User> GetList(VMS_Sys_User searchModel);

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		PageData GetPageListByRoleCode(string roleCode, UserSession sessionCurrent);

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <returns></returns>
		List<SelectListItem> GetSelectListItemsByRoleCode(string roleCode, UserSession sessionCurrent, List<int> selected = null);

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <returns></returns>
		List<SelectListItem> GetSelectListItemsByRoleCode(string roleCode, UserSession sessionCurrent, int selected);

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleID"></param>
		/// <returns></returns>
		PageData GetPageListByRoleID(int roleID);

		/// <summary>
		/// 根据id获取用户的详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		SysUserDetail GetDetail(int id);

		/// <summary>
		/// 根据登录账号获取用户的详细信息
		/// </summary>
		/// <param name="code"></param>
		/// <returns></returns>
		SysUserDetail GetDetailByCode(string code);

		/// <summary>
		/// 通过登录帐号查询用户
		/// </summary>
		/// <param name="code"></param>
		/// <returns></returns>
		Sys_User GetByCode(string code);

		/// <summary>
		/// 用户名和密码登录
		/// </summary>
		/// <param name="code"></param>
		/// <param name="passwd"></param>
		/// <returns></returns>
		UserSession Login(string code, string passwd);

		/// <summary>
		/// 修改密码
		/// </summary>
		/// <param name="oldPasswd"></param>
		/// <param name="newPasswd"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool ChangePasswd(string oldPasswd, string newPasswd, UserSession sessionCurrent);

		/// <summary>
		/// 审核
		/// </summary>
		/// <param name="id"></param>
		/// <param name="state"></param>
		/// <returns></returns>
		bool Audit(int id, int state, string remark, UserSession sessionCurrent);

		/// <summary>
		/// 删除用户
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool Delete(int id, UserSession sessionCurrent);

		/// <summary>
		/// 批量删除用户
		/// </summary>
		bool BatchDelete(int[] ids, UserSession sessionCurrent);

		/// <summary>
		/// 重置密码
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool ResetPasswd(int id, UserSession sessionCurrent);

		/// <summary>
		/// 检验登录账号是否可用
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool ValidateCode(int id, string code, UserSession sessionCurrent);

		/// <summary>
		/// 新增或修改保存
		/// </summary>
		int AddOrUpdate(Sys_User model, UserSession sessionCurrent);

		/// <summary>
		/// 小程序注册
		/// </summary>
		/// <param name="oauthType"></param>
		/// <param name="appID"></param>
		/// <param name="sessionCurrent"></param>
		/// <param name="user"></param>
		/// <param name="oauthDetail"></param>
		/// <returns></returns>
		UserSession Register(SessionType oauthType, string appID, UserSession sessionCurrent, Sys_User user, SysOAuthDetail oauthDetail);
	}

	public partial class ServiceSysUser
	{
		private readonly IServiceSysUserRole serviceSysUserRole;
		private readonly IServiceSysOAuth serviceSysOAuth;
		private readonly IServiceSysUserOAuth serviceSysUserOAuth;
		private readonly IServiceSysRole serviceSysRole;
		private readonly IServiceSysLog serviceSysLog;
		private readonly IServiceSysTableLog serviceSysTableLog;
		private readonly IServiceSysSession serviceSysSession;
		private readonly string DEFAULT_PASSWD = "1";

		public ServiceSysUser(BuzContext ctx,
			IServiceSysUserRole _serviceSysUserRole,
			IServiceSysOAuth _serviceSysOAuth,
			IServiceSysUserOAuth _serviceSysUserOAuth,
			IServiceSysRole _serviceSysRole,
			IServiceSysLog _serviceSysLog,
			IServiceSysTableLog _serviceSysTableLog,
			IServiceSysSession _serviceSysSession,
			ILogger<ServiceSysUser> log)
		{
			serviceSysUserRole = _serviceSysUserRole;
			serviceSysOAuth = _serviceSysOAuth;
			serviceSysUserOAuth = _serviceSysUserOAuth;
			serviceSysRole = _serviceSysRole;
			serviceSysLog = _serviceSysLog;
			serviceSysTableLog = _serviceSysTableLog;
			serviceSysSession = _serviceSysSession;
			context = ctx;
			logger = log;
		}

		/// <summary>
		/// 根据id获取用户的详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public SysUserDetail GetDetail(int id)
		{
			SysUserDetail user = null;
			try
			{
				user = (from u in context.SysUser
						join o in context.SysOrganization on u.OrgID equals o.ID into otmp
						from oall in otmp.DefaultIfEmpty()
						join d in context.SysDept on u.DeptID equals d.ID into dtmp
						from dall in dtmp.DefaultIfEmpty()
						where u.ID == id
						select new SysUserDetail()
						{
							Name = u.Name,
							IDCardNo = u.IDCardNo,
							Mobile = u.Mobile,
							OrgName = oall.Name,
							DeptName = dall.Name
						}).SingleOrDefault();
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return user;
		}

		/// <summary>
		/// 获取用户详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public Sys_User GetViewDetail(int id, UserSession sessionCurrent)
		{
			Sys_User model = null;
			try
			{
				var query = from u in context.SysUser
							join o in context.SysOrganization on u.OrgID equals o.ID into uotmp
							from uo in uotmp.DefaultIfEmpty()
							join d in context.SysDept on u.DeptID equals d.ID into udtmp
							from ud in udtmp.DefaultIfEmpty()
							where u.ID == id
							select new
							{
								User = u,
								Dept = ud,
								OrgName = uo.Name
							};
				var result = query.SingleOrDefault();
				if (result == null)
				{
					throw new BuzException("参数有误");
				}
				model = result.User;
				model.DeptName = result.Dept != null ? result.Dept.Name : "";
				model.OrgName = result.OrgName;
				model.RolesID = serviceSysUserRole.GetRolesList(model.ID);
				model.RolesName = serviceSysRole.GetNames(model.RolesID);
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return model;
		}

		/// <summary>
		/// 获取用户详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public Sys_User GetEditDetail(int id, UserSession sessionCurrent)
		{
			return GetViewDetail(id, sessionCurrent);
		}

		/// <summary>
		/// 根据登录账号获取用户的详细信息
		/// </summary>
		/// <param name="code"></param>
		/// <returns></returns>
		public SysUserDetail GetDetailByCode(string code)
		{
			SysUserDetail user = null;
			try
			{
				if (string.IsNullOrEmpty(code))
				{
					throw new ArgumentException("登录帐号不能为空");
				}
				var model = context.SysUser.SingleOrDefault(m => m.Code == code);
				if (model != null)
				{
					user = new SysUserDetail()
					{
						Name = model.Name,
						IDCardNo = model.IDCardNo,
						Mobile = model.Mobile
					};
				}
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return user;
		}

		/// <summary>
		/// 通过登录帐号查询用户
		/// </summary>
		/// <param name="code"></param>
		/// <returns></returns>
		public Sys_User GetByCode(string code)
		{
			try
			{
				if (string.IsNullOrEmpty(code))
				{
					throw new BuzException("登录帐号不能为空");
				}
				var model = context.SysUser.SingleOrDefault(m => m.Code == code);
				return model;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 生成用户会话信息
		/// </summary>
		/// <param name="user"></param>
		/// <param name="oauth"></param>
		/// <param name="session"></param>
		/// <param name="updateRoles">是否更新当前会话里的用户角色信息</param>
		/// <returns></returns>
		private UserSession GetUserSession(Sys_User user, Sys_OAuth oauth, Sys_Session session, bool updateRoles = true)
		{
			if (user == null || oauth == null || session == null)
			{
				throw new ArgumentException("生成用户会话信息参数不能为空");
			}
			if (user.RolesID == null)
			{
				user.RolesID = new List<int>();
			}
			int[] roles = user.RolesID.ToArray();
			UserSession userSession = new UserSession()
			{
				OrgID = user.OrgID,
				//OrgName = user.OrgName,
				DeptID = user.DeptID,
				//DeptName = user.DeptName,
				RoleType = user.RoleType,
				UserType = user.UserType,
				Avatar = user.AvatarUrl ?? "",
				SessionType = session.Type,
				Sessionkey = session.SessionKey,
				Timestamp = session.LastVisit.Ticks,
				SessionID = session.ID,
				UserID = user.ID,
				UserCode = user.Code,
				State = user.StateNow,
				UserName = user.Name,
				Roles = roles,
				OpenID = oauth.OpenID,
				UnionID = oauth.UnionID,
			};
			//if (updateRoles)
			//{
			//	userSession.Roles = serviceUserRole.GetRolesArray(user.ID);
			//}
			return userSession;
		}

		/// <summary>
		/// 生成用户会话信息
		/// </summary>
		/// <param name="user"></param>
		/// <param name="oauth"></param>
		/// <param name="session"></param>
		/// <param name="updateRoles">是否更新当前会话里的用户角色信息</param>
		/// <returns></returns>
		private UserSession GetUserSession(Sys_User user, Sys_Session session, int[] roles)
		{
			if (user == null || session == null)
			{
				throw new ArgumentException("生成用户会话信息参数不能为空");
			}

			UserSession userSession = new UserSession()
			{
				OrgID = user.OrgID,
				//OrgName = user.OrgName,
				DeptID = user.DeptID,
				//DeptName = user.DeptName,
				RoleType = user.RoleType,
				UserType = user.UserType,
				Avatar = user.AvatarUrl ?? "",
				SessionType = session.Type,
				Sessionkey = session.SessionKey,
				Timestamp = session.LastVisit.Ticks,
				SessionID = session.ID,
				UserID = user.ID,
				UserCode = user.Code,
				State = user.StateNow,
				UserName = user.Name,
				Roles = roles
			};
			return userSession;
		}

		/// <summary>
		/// 用户名和密码登录
		/// </summary>
		/// <param name="code"></param>
		/// <param name="passwd"></param>
		/// <returns></returns>
		public UserSession Login(string code, string passwd)
		{
			UserSession authSession = null;
			try
			{
				if (string.IsNullOrEmpty(code) || string.IsNullOrEmpty(passwd))
				{
					throw new BuzException("用户名或密码不能为空");
				}

				DateTime dtNow = DateTime.Now;
				string ip = GetRequestIP();

				var user = context.SysUser.SingleOrDefault(m => m.Code == code);
				if (user == null)
				{
					throw new BuzException("未查询到相关帐户信息");
				}
				if (string.Compare(EncryptHelper.SHA1Hash(passwd + user.PasswdSalt), user.Passwd) != 0)
				{
					throw new BuzException("密码有误");
				}
				if (user.StateNow != (int)UserState.正常)
				{
					throw new BuzException("用户帐户状态异常：" + user.StateNow);
				}
				var session = context.SysSession.SingleOrDefault(m => m.UserID == user.ID && m.Type == (int)SessionType.用户名);
				if (session == null)
				{
					throw new BuzException("会话信息为空");
				}
				int[] roles = serviceSysUserRole.GetRolesArray(user.ID);
				var orgName = (from o in context.SysOrganization where o.ID == user.ID select o.Name).SingleOrDefault();
				var deptName = (from d in context.SysDept where d.ID == user.DeptID select d.Name).SingleOrDefault();

				#region 更新会话时间
				session.LastVisit = dtNow;
				session.LastVisitIP = ip;
				context.SaveChanges();
				#endregion

				#region 更新用户信息
				DateTime? lastLoginDateOld = user.LastLoginDate;
				string lastLoginIPOld = user.LastLoginIP;
				user.LastLoginDate = dtNow;
				user.LastLoginIP = ip;
				user.OrgName = orgName;
				user.DeptName = deptName;
				context.SaveChanges();
				user.LastLoginDate = lastLoginDateOld;//再设置回去
				user.LastLoginIP = lastLoginIPOld;
				#endregion

				authSession = GetUserSession(user, session, roles);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (DbUpdateException ex)
			{
				logger.LogError(ex.InnerException ?? ex, "用户登录出错");
				throw new BuzException("登录失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "用户登录出错");
				throw new BuzException("登录失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}

			return authSession;
		}

		/// <summary>
		/// 修改密码
		/// </summary>
		/// <param name="oldPasswd"></param>
		/// <param name="newPasswd"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool ChangePasswd(string oldPasswd, string newPasswd, UserSession sessionCurrent)
		{
			try
			{
				if (sessionCurrent == null)
				{
					throw new BuzException("用户未登录或登录已超时");
				}

				DateTime dtNow = DateTime.Now;

				var user = context.SysUser.SingleOrDefault(m => m.ID == sessionCurrent.UserID);
				if (user == null)
				{
					throw new BuzException("未查询到相关帐户信息");
				}
				if (string.Compare(EncryptHelper.SHA1Hash(oldPasswd + user.PasswdSalt), user.Passwd) != 0)
				{
					throw new BuzException("原密码有误");
				}
				user.PasswdSalt = Guid.NewGuid().ToString("N");
				user.Passwd = EncryptHelper.SHA1Hash(newPasswd + user.PasswdSalt);
				context.SaveChanges();

				return true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (DbUpdateException ex)
			{
				logger.LogError(ex.InnerException ?? ex, "修改密码出错");
				throw new BuzException("修改密码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "修改密码出错");
				throw new BuzException("修改密码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 审核
		/// </summary>
		/// <param name="id"></param>
		/// <param name="state"></param>
		/// <returns></returns>
		public bool Audit(int id, int state, string remark, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				if (logger.IsEnabled(LogLevel.Debug))
				{
					logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				}
				if (state != (int)UserState.正常 && state != (int)UserState.未绑定)
				{
					throw new BuzException("审核状态信息有误");
				}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				Sys_User user = null;
				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						//DateTime dtNow = DateTime.Now;
						//string ip = GetRequestIP();

						user = context.SysUser.SingleOrDefault(m => m.ID == id);
						if (user == null)
						{
							throw new BuzException("未找到相关记录");
						}
						user.StateNow = state;
						context.SaveChanges();
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "审核信息出错");
				throw new BuzException("审核信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 删除具体操作
		/// </summary>
		/// <param name="id"></param>
		/// <param name="ip"></param>
		/// <param name="dtNow"></param>
		/// <param name="sessionCurrent"></param>
		protected void DeleteWithinTrans(int id, string ip, DateTime dtNow, UserSession sessionCurrent)
		{
			Sys_User modelOld = Get(id, true);
			//删除会话信息
			serviceSysSession.DeleteByUserID(id);
			//删除权限信息
			serviceSysUserRole.DeleteByUserID(id);
			//删除第三方登录信息
			serviceSysOAuth.DeleteByUserID(id);
			//删除第三方登录绑定信息
			serviceSysUserOAuth.DeleteByUserID(id);

			//其他扩展
			onDelete(id);

			Delete(modelOld);

			serviceSysLog.Add(sessionCurrent, ip, $"删除用户{modelOld.Name}[{modelOld.Code}]信息，原信息：", modelOld, dtNow);
		}

		/// <summary>
		/// 删除用户
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool Delete(int id, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						DeleteWithinTrans(id, ip, dtNow, sessionCurrent);

						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "删除用户出错");
				throw new BuzException("删除用户失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 批量删除用户
		/// </summary>
		/// <returns></returns>
		public bool BatchDelete(int[] ids, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				if (ids == null || ids.Length == 0)
				{
					throw new BuzException("参数不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();
						foreach (int id in ids)
						{
							DeleteWithinTrans(id, ip, dtNow, sessionCurrent);
						}
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "批量删除用户出错");
				throw new BuzException("批量删除用户失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 重置密码
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool ResetPasswd(int id, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						var user = Get(id);
						user.PasswdSalt = Guid.NewGuid().ToString("N");
						user.Passwd = EncryptHelper.SHA1Hash(DEFAULT_PASSWD + user.PasswdSalt);
						context.SaveChanges();

						serviceSysLog.Add(sessionCurrent, ip, $"重置用户{user.Name}[{user.Code}]的登录密码", dtNow);
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "重置密码出错");
				throw new BuzException("重置密码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 检验登录账号是否可用
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool ValidateCode(int id, string code, UserSession sessionCurrent)
		{
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}
				if (string.IsNullOrEmpty(code))
				{
					throw new BuzException("登录账号不能为空");
				}
				if (id == 0)
				{
					return !context.SysUser.Any(m => m.Code == code);
				}
				var lst = (from u in context.SysUser where u.Code == code select u.ID).ToList();
				if (lst.Count == 0)
				{
					return true;
				}
				return lst[0] == id;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "检验登录账号是否可用出错");
				throw new BuzException("检验登录账号是否可用失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		private IQueryable<VML_Sys_User> GetQuery(VMS_Sys_User searchModel)
		{
			var query = from u in context.SysUser
						join o in context.SysOrganization on u.OrgID equals o.ID into uotmp
						from uo in uotmp.DefaultIfEmpty()
						join d in context.SysDept on u.DeptID equals d.ID into udtmp
						from ud in udtmp.DefaultIfEmpty()
						where !string.IsNullOrEmpty(u.Name) && u.NickName != "微信用户"
							//join ur in context.SysUserRole on u.ID equals ur.UserID
						select new VML_Sys_User()
						{
							ID = u.ID,
							Name = u.Name,
							PYCode = u.PYCode,
							BirthDate = u.BirthDate,
							Country = u.Country,
							Province = u.Province,
							City = u.City,
							District = u.District,
							Town = u.Town,
							DetailAddress = u.DetailAddress,
							AvatarUrl = u.AvatarUrl,
							Email = u.Email,
							LastLoginIP = u.LastLoginIP,
							LastLoginDate = u.LastLoginDate,
							NickName = u.NickName,
							Phone = u.Phone,
							IDCardNo = u.IDCardNo,
							Code = u.Code,
							Gender = u.Gender,
							Mobile = u.Mobile,
							AddDate = u.AddDate,
							DeptID = u.DeptID,
							DeptName = ud.Name,
							OrgName = uo.Name,
							StateNow = u.StateNow,
							RoleType = u.RoleType,
							UserType = u.UserType,
							OrgID = u.OrgID
							//RolesID = ur.,
						};
			if (!string.IsNullOrWhiteSpace(searchModel.name))
			{
				query = query.Where(m => EF.Functions.Like(m.Name, "%" + searchModel.name + "%"));
			}
			if (!string.IsNullOrEmpty(searchModel.code))
			{
				query = query.Where(m => m.Code == searchModel.code);
			}
			if (!string.IsNullOrEmpty(searchModel.idcardno))
			{
				query = query.Where(m => m.IDCardNo.Contains(searchModel.idcardno));
			}
			if (!string.IsNullOrEmpty(searchModel.mobile))
			{
				query = query.Where(m => m.Mobile == searchModel.mobile);
			}
			if (searchModel.deptid.HasValue && searchModel.deptid.Value > 0)
			{
				var children = context.ExecuteReader<TreeIdentity>(
					"sp_sys_get_tree_children",
					new SqlParameter[] { new SqlParameter("@id", searchModel.deptid.Value), new SqlParameter("@table_name", "Sys_Dept") }
				);
				if (children.Count > 0)
				{
					List<int> lstTree = new List<int>();
					foreach (var c in children)
					{
						lstTree.Add(c.ID);
					}
					query = query.Where(m => lstTree.Contains(m.DeptID));
				}
			}
			if (searchModel.adddate_s != DateTime.MinValue)
			{
				query = query.Where(m => m.AddDate >= searchModel.adddate_s);
			}
			if (searchModel.adddate_e != DateTime.MinValue)
			{
				query = query.Where(m => m.AddDate <= searchModel.adddate_e);
			}
			if (searchModel.gender.HasValue)
			{
				query = query.Where(m => m.Gender == searchModel.gender.Value);
			}
			if (searchModel.state.HasValue)
			{
				query = query.Where(m => m.StateNow == searchModel.state.Value);
			}
			if (searchModel.roletype.HasValue)
			{
				query = query.Where(m => m.RoleType == searchModel.roletype.Value);
			}
			if (searchModel.roles != null && searchModel.roles.Length > 0)
			{
				//todo://增加角色过滤
			}
			if (searchModel.ids != null && searchModel.ids.Length > 0)
			{
				query = query.Where(m => searchModel.ids.Contains(m.ID));
			}
			if (searchModel.orgids != null && searchModel.orgids.Length > 0)
			{
				query = searchModel.orgids.Length == 1 ? query.Where(m => m.OrgID == searchModel.orgids[0]) : query.Where(m => searchModel.orgids.Contains(m.OrgID));
			}
			switch (searchModel.sortby)
			{
				case "Code":
					////数据库分页，不支持多表
					//query = query.OrderByDescending(e => EF.Property<object>(e, sortOrder));
					////内存分页
					////query = query.OrderByDescending(e => e.GetType().GetProperty(sortOrder).GetValue(e, null));
					query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Code) : query.OrderByDescending(e => e.Code);
					break;
				case "Name":
					query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Name) : query.OrderByDescending(e => e.Name);
					break;
				case "StateNow":
					query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.StateNow) : query.OrderByDescending(e => e.StateNow);
					break;
				default:
					query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.ID) : query.OrderByDescending(e => e.ID);
					break;
			}
			return query;
		}

		/// <summary>
		/// 分页列表
		/// </summary>
		public PageData GetPageList(VMS_Sys_User searchModel)
		{
			PageData result = null;
			try
			{
				searchModel.Validate();

				var query = GetQuery(searchModel);

				result = new PageData(searchModel.pnum.Value, searchModel.psize.Value);
				result.Load(query);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 列表
		/// </summary>
		public List<VML_Sys_User> GetList(VMS_Sys_User searchModel)
		{
			try
			{
				//searchModel.Validate();

				var query = GetQuery(searchModel);

				if (searchModel.pnum > 0 && searchModel.psize > 0)
				{
					if (searchModel.pnum.Value > 1)
					{
						query = query.Skip(searchModel.psize.Value * (searchModel.pnum.Value - 1));
					}
					query = query.Take(searchModel.psize.Value);
				}

				return query.ToList();
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取列表数据出错");
				throw new BuzException("获取列表数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 新增或修改保存
		/// </summary>
		public int AddOrUpdate(Sys_User model, UserSession sessionCurrent)
		{
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}
				if (model == null)
				{
					throw new BuzException("参数不能为空");
				}

				if (model.RolesID == null || model.RolesID.Count < 1)
				{
					throw new BuzException("用户角色不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						if (model.ID > 0)
						{
							if (context.SysUser.Any(m => m.Code == model.Code && m.ID != model.ID))
							{
								throw new BuzException("登录账号重复");
							}
							Update(model);

							//serviceSysTableLog.Add(sessionCurrent, TableCode.Sys_User, model.ID, ip, "修改用户信息，新信息如下：", model, dtNow, true);

							var lstRoleIDOld = (from ur in context.SysUserRole
												where ur.UserID == model.ID
												select ur.RoleID).ToList();
							var lstDeleted = lstRoleIDOld.Except(model.RolesID);//找出删掉的
							var lstNew = model.RolesID.Except(lstRoleIDOld).ToList();//找出新的
							foreach (var d in lstDeleted)
							{
								//SqlParameter[] paras = new SqlParameter[]{
								//		new SqlParameter("@GoodsID",detail.Detail.GoodsID),
								//	};
								context.Database.ExecuteSqlRaw("DELETE FROM Sys_UserRole WHERE UserID={0} AND RoleID={1}", model.ID, d);
							}

							foreach (var r in lstNew)
							{
								Sys_UserRole ur = new Sys_UserRole()
								{
									AddDate = dtNow,
									AddManID = sessionCurrent.UserID,
									AddManName = sessionCurrent.UserName,
									UserID = model.ID,
									AuthValid = true,
									RoleID = r
								};
								serviceSysUserRole.Add(ur);
							}
							context.SaveChanges();
						}
						else
						{
							if (context.SysUser.Any(m => m.Code == model.Code))
							{
								throw new BuzException("登录账号重复");
							}
							model.PasswdSalt = Guid.NewGuid().ToString("N");
							model.Passwd = EncryptHelper.SHA1Hash(DEFAULT_PASSWD + model.PasswdSalt);
							model.AddDate = dtNow;
							model.AddManID = sessionCurrent.UserID;
							model.AddManName = sessionCurrent.UserName;
							model.StateNow = (int)UserState.正常;
							Add(model);

							foreach (int roleID in model.RolesID)
							{
								Sys_UserRole ur = new Sys_UserRole()
								{
									AddDate = dtNow,
									AddManID = sessionCurrent.UserID,
									AddManName = sessionCurrent.UserName,
									UserID = model.ID,
									AuthValid = true,
									RoleID = roleID
								};
								serviceSysUserRole.Add(ur);
							}

							Sys_Session session = new Sys_Session()
							{
								AddTime = dtNow,
								LastUpdate = dtNow,
								Type = (int)SessionType.用户名,
								UserID = model.ID
							};
							serviceSysSession.Add(session);
							context.SaveChanges();
						}

						#endregion

						trans.Commit();

						return model.ID;
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "保存对象信息出错");
				throw new BuzException("数据库保存失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 小程序注册
		/// </summary>
		/// <param name="oauthType"></param>
		/// <param name="appID"></param>
		/// <param name="sessionCurrent"></param>
		/// <param name="user"></param>
		/// <param name="oauthDetail"></param>
		/// <returns></returns>
		public UserSession Register(SessionType oauthType, string appID, UserSession sessionCurrent, Sys_User user, SysOAuthDetail oauthDetail)
		{
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null || string.IsNullOrEmpty(sessionCurrent.OpenID))
				{
					throw new BuzException("当前会话不能为空");
				}
				if (string.IsNullOrEmpty(appID))
				{
					throw new BuzException("小程序ID不能为空");
				}
				if (user == null)
				{
					throw new BuzException("用户信息不能为空");
				}
				if (oauthDetail == null)
				{
					throw new BuzException("第三方授权信息不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						Sys_OAuth oauth = context.SysOAuth.SingleOrDefault(e => e.AppID == appID && e.OpenID == sessionCurrent.OpenID);
						if (oauth == null)
						{
							throw new BuzException("第三方登录信息不存在");
						}
						oauth.Type = (int)oauthType;
						oauth.LastUpdate = dtNow;
						oauth.LastVisit = dtNow;
						oauth.NickName = oauthDetail.NickName;
						oauth.Gender = oauthDetail.Gender;
						oauth.Country = oauthDetail.Country;
						oauth.Province = oauthDetail.Province;
						oauth.City = oauthDetail.City;
						oauth.AvatarUrl = oauthDetail.AvatarUrl;
						oauth.Authorized = true;
						context.SaveChanges();

						Sys_User userOld = context.SysUser.SingleOrDefault(e => e.ID == oauth.UserID);
						if (userOld == null)
						{
							throw new BuzException("第三方登录用户信息不存在");
						}
						userOld.NickName = oauthDetail.NickName;
						userOld.Gender = oauthDetail.Gender;
						userOld.Country = oauthDetail.Country;
						userOld.Province = oauthDetail.Province;
						userOld.City = oauthDetail.City;
						userOld.AvatarUrl = oauthDetail.AvatarUrl;
						userOld.LastLoginIP = ip;
						userOld.LastLoginDate = dtNow;
						#region 自定义需要设置哪些信息
						userOld.Name = user.Name;
						userOld.IDCardNo = user.IDCardNo;
						userOld.OrgID = user.OrgID;
						userOld.DetailAddress = user.DetailAddress;
						userOld.WorkUnit = user.WorkUnit;
						userOld.Mobile = user.Mobile;
						userOld.RoleType = user.RoleType;
						userOld.UserType = user.UserType;
						#endregion
						if (userOld.StateNow == (int)UserState.未绑定 || userOld.StateNow == (int)UserState.未授权)
						{
							userOld.StateNow = (int)UserState.正常;
						}
						context.SaveChanges();

						Sys_Session session = context.SysSession.SingleOrDefault(e => e.UserID == oauth.UserID && e.Type == (int)oauthType);
						if (session == null)
						{
							throw new BuzException("第三方登录用户会话信息不存在");
						}
						session.LastUpdate = dtNow;
						session.LastVisit = dtNow;
						session.LastVisitIP = ip;
						context.SaveChanges();

						#region 处理用户角色
						if (userOld.RolesID == null)
						{
							userOld.RolesID = new List<int>();
						}
						if (user.RolesID != null && user.RolesID.Count > 0)
						{
							userOld.RolesID.AddRange(user.RolesID);
						}
						var lstRolesOld = (from ur in context.SysUserRole
										   where ur.UserID == oauth.UserID
										   select ur.RoleID).ToList();
						var lstRolesDeleted = lstRolesOld.Except(userOld.RolesID);//找出删掉的
						var lstRolesNew = userOld.RolesID.Except(lstRolesOld).ToList();//找出新的
						foreach (var d in lstRolesDeleted)
						{
							context.Database.ExecuteSqlRaw("DELETE FROM Sys_UserRole WHERE UserID={0} AND RoleID={1}", oauth.UserID, d);
						}

						foreach (var r in lstRolesNew)
						{
							Sys_UserRole ur = new Sys_UserRole()
							{
								AddDate = dtNow,
								AddManID = sessionCurrent.UserID,
								AddManName = sessionCurrent.UserName,
								UserID = oauth.UserID,
								AuthValid = true,
								RoleID = r
							};
							serviceSysUserRole.Add(ur);
						}
						context.SaveChanges();
						#endregion

						#region 其他注册操作
						OnRegister(userOld, oauth, session);
						#endregion

						#endregion

						trans.Commit();

						return GetUserSession(userOld, oauth, session, false);
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "保存对象信息出错");
				throw new BuzException("数据库保存失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRoleCode(string roleCode, UserSession sessionCurrent)
		{
			IQueryable<VM_Sys_UserSelect> query = null;
			if (string.IsNullOrEmpty(roleCode))
			{
				query = from u in context.SysUser
						where u.OrgID == sessionCurrent.OrgID
						&& !string.IsNullOrEmpty(u.Name)
						select new VM_Sys_UserSelect()
						{
							ID = u.ID,
							Name = u.Name
						};
			}
			else
			{
				query = context.SysUserRole
						.Join(context.SysRole.Where(m => m.Code == roleCode), ur => ur.RoleID, r => r.ID, (ur, r) => ur.UserID)
						.Distinct()
						.Join(context.SysUser, x => x, u => u.ID, (x, u) => new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name, OrgID = u.OrgID }).Where(x => x.OrgID == sessionCurrent.OrgID);
			}
			query = query.OrderBy(e => e.ID);
			return query;
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRoleCode(string roleCode, UserSession sessionCurrent)
		{
			PageData result = null;
			try
			{
				var list = GetQueryByRoleCode(roleCode, sessionCurrent).ToList();
				result = new PageData();
				result.list = list;
				result.pnum = 1;
				result.psize = list.Count;
				result.total = list.Count;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <returns></returns>
		public List<SelectListItem> GetSelectListItemsByRoleCode(string roleCode, UserSession sessionCurrent, List<int> selected = null)
		{
			var result = GetQueryByRoleCode(roleCode, sessionCurrent).ToList();
			List<SelectListItem> lst = new List<SelectListItem>();
			if (selected == null || selected.Count == 0)
			{
				foreach (var m in result)
				{
					SelectListItem item = new SelectListItem()
					{
						Value = m.ID.ToString(),
						Text = m.Name.ToString()
					};
					lst.Add(item);
				}
			}
			else
			{
				foreach (var m in result)
				{
					SelectListItem item = new SelectListItem()
					{
						Value = m.ID.ToString(),
						Text = m.Name.ToString(),
						Selected = selected.Contains(m.ID)
					};
					lst.Add(item);
				}
			}
			return lst;
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <returns></returns>
		public List<SelectListItem> GetSelectListItemsByRoleCode(string roleCode, UserSession sessionCurrent, int selected)
		{
			var result = GetQueryByRoleCode(roleCode, sessionCurrent).ToList();
			List<SelectListItem> lst = new List<SelectListItem>();
			foreach (var m in result)
			{
				SelectListItem item = new SelectListItem()
				{
					Value = m.ID.ToString(),
					Text = m.Name.ToString(),
					Selected = selected == m.ID
				};
				lst.Add(item);
			}
			return lst;
		}

		/// <summary>
		/// 获取具有指定任一角色的用户信息
		/// </summary>
		/// <param name="rolesCode"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRolesCodeAny(string[] rolesCode)
		{
			if (rolesCode == null || rolesCode.Length == 0)
			{
				throw new BuzException("角色不能为空");
			}
			var query = context.SysUserRole
					.Join(context.SysRole.Where(m => rolesCode.Contains(m.Code)), ur => ur.RoleID, r => r.ID, (ur, r) => ur.UserID)
					.Distinct()
					.Join(context.SysUser, x => x, u => u.ID, (x, u) => new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name });
			query = query.OrderBy(e => e.ID);
			return query;
		}

		/// <summary>
		/// 获取具有指定任一角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRolesCodeAny(string[] rolesCode)
		{
			PageData result;
			try
			{
				var list = GetQueryByRolesCodeAny(rolesCode).ToList();
				result = new PageData();
				result.list = list;
				result.pnum = 1;
				result.psize = list.Count;
				result.total = list.Count;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 获取具有指定全部角色的用户信息
		/// </summary>
		/// <param name="rolesCode"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRolesCodeAll(string[] rolesCode)
		{
			if (rolesCode == null || rolesCode.Length == 0)
			{
				throw new BuzException("角色不能为空");
			}
			int rolesCount = rolesCode.Length;
			var queryAll = from u in context.SysUser
						   join gall in (from urall in (from ur in context.SysUserRole
														join r in context.SysRole on ur.RoleID equals r.ID
														where rolesCode.Contains(r.Code)
														select ur.UserID)//可以单字段，也可以筛选多字段，多字段的时候分组的时候需要指定分组变量，但是多字段的时候分组结果为空时会报错
										 group urall by urall into uralltmp
										 //let Total = uralltmp.Count()
										 where uralltmp.Count() == rolesCount//不能使用临时变量筛选，需要使用组函数，比较的值也应该先保存到临时变量中，不能使用Length等属性
										 select new { uralltmp.Key })
							//select new { uralltmp.Key,Total=Total })
							on u.ID equals gall.Key
						   select new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name };
			return queryAll;
		}

		/// <summary>
		/// 获取具有指定全部角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRolesCodeAll(string[] rolesCode)
		{
			PageData result;
			try
			{
				var list = GetQueryByRolesCodeAll(rolesCode).ToList();
				result = new PageData();
				result.list = list;
				result.pnum = 1;
				result.psize = list.Count;
				result.total = list.Count;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleID"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRoleID(int roleID)
		{
			if (roleID <= 0)
			{
				throw new BuzException("角色不能为空");
			}
			var query = context.SysUserRole.Where(m => m.RoleID == roleID)
				.Select(x => x.UserID)
				.Distinct()
				.Join(context.SysUser, x => x, u => u.ID, (x, u) => new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name });
			query = query.OrderBy(e => e.ID);
			return query;
		}

		/// <summary>
		/// 获取具有指定角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRoleID(int roleID)
		{
			PageData result;
			try
			{
				var list = GetQueryByRoleID(roleID).ToList();
				result = new PageData();
				result.Load(list);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 获取具有指定任一角色的用户信息
		/// </summary>
		/// <param name="rolesID"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRolesIDAny(int[] rolesID)
		{
			if (rolesID == null || rolesID.Length == 0)
			{
				throw new BuzException("角色不能为空");
			}
			var query = context.SysUserRole.Where(m => rolesID.Contains(m.RoleID))
				.Select(x => x.UserID)
				.Distinct()
				.Join(context.SysUser, x => x, u => u.ID, (x, u) => new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name });
			query = query.OrderBy(e => e.ID);
			return query;
		}

		/// <summary>
		/// 获取具有指定任一角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRolesIDAny(int[] rolesID)
		{
			PageData result;
			try
			{
				var list = GetQueryByRolesIDAny(rolesID).ToList();
				result = new PageData();
				result.Load(list);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 获取具有指定全部角色的用户信息
		/// </summary>
		/// <param name="rolesID"></param>
		/// <returns></returns>
		private IQueryable<VM_Sys_UserSelect> GetQueryByRolesIDAll(int[] rolesID)
		{
			int rolesCount = rolesID.Length;
			var queryAll = from u in context.SysUser
						   join gall in (from urall in (from ur in context.SysUserRole
														where rolesID.Contains(ur.RoleID)
														select ur.UserID)//可以单字段，也可以筛选多字段，多字段的时候分组的时候需要指定分组变量，但是多字段的时候分组结果为空时会报错
										 group urall by urall into uralltmp
										 //let Total = uralltmp.Count()
										 where uralltmp.Count() == rolesCount//不能使用临时变量筛选，需要使用组函数，比较的值也应该先保存到临时变量中，不能使用Length等属性
										 select new { uralltmp.Key })
							//select new { uralltmp.Key,Total=Total })
							on u.ID equals gall.Key
						   select new VM_Sys_UserSelect() { ID = u.ID, Name = u.Name };
			return queryAll;
		}

		/// <summary>
		/// 获取具有指定全部角色的用户信息
		/// </summary>
		/// <param name="roleCode"></param>
		/// <returns></returns>
		public PageData GetPageListByRolesIDAll(int[] rolesID)
		{
			PageData result;
			try
			{
				var list = GetQueryByRolesIDAll(rolesID).ToList();
				result = new PageData();
				result.list = list;
				result.pnum = 1;
				result.psize = list.Count;
				result.total = list.Count;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}
	}
}